﻿#ifndef _tcp_server_event_impl_20220427_
#define _tcp_server_event_impl_20220427_


#include <thread>
#include <map>
#include <list>
#include <mutex>
#include <memory>

#include "event2/event.h"
#include "event2/util.h"
#include "event2/event_compat.h"
#include "event2/event_struct.h"
#include "event2/bufferevent.h"
#include "event2/thread.h"

#include <event2/buffer.h>
#include <event2/listener.h>

//#include "SL_asynFramePub.h"
#include "SL_tcpClient_event_impl.h"
#include "SL_tcpClient.h"
#include "SL_tcpServer.h"

class SLTcpServerEventImpl : public SLTcpServer
{
	struct _tcp_listen_info
	{
		~_tcp_listen_info() {
			if (listener) { evconnlistener_free(listener); }
		}
		SLTcpServerEventImpl* pserver = nullptr;
		int m_ip = 0;
		int m_port = 0;
		struct evconnlistener *listener = nullptr;
	};
public:

	SLTcpServerEventImpl();
	virtual ~SLTcpServerEventImpl();

	virtual int init(SLTcpServerCB* pcb);
	virtual void uninit() {}
	virtual void start();
	virtual void stop() {}
	virtual int addListen(std::string _ip, int& _port);
    virtual int delListen(std::string _ip, int _port);

	virtual SLTcpClientPtr   createClient();

	void pushEvent(SLTcpClientEventImpl::_tcp_event_infoStpr pevInfo);
private:
	static void checkTimeOut_g(evutil_socket_t fd, short event, void* arg);
	void checkTimeOut();

	void thread_listen();
	static void listener_cb(struct evconnlistener* listener, evutil_socket_t fd,struct sockaddr* sa, int socklen, void* user_data);
	void listener_cb_fun(struct evconnlistener* listener, evutil_socket_t fd,struct sockaddr* sa, int socklen, _tcp_listen_info* _plistenInfo);

	static void eventNotify_cb_g(evutil_socket_t fd, short event, void* arg) {((SLTcpServerEventImpl*)arg)->eventNotify_cb(fd, event);}
	void eventNotify_cb(evutil_socket_t fd, short event);
	void eventNotify_cb_fun(SLTcpClientEventImpl::_tcp_event_info *_evinfo);

	void NetClose(int socket);
public:
	struct event_base* m_base = nullptr;
private:
	//std::map<uint64_t, _tcp_listen_info>	m_listenMap; //key为监听socket
	std::map<int, SLTcpClientEventImplPtr>  m_clientMap; //key 数据socket
    std::map<std::string, std::shared_ptr<_tcp_listen_info>>  m_connect_info;

	//事件
	evutil_socket_t m_event_pair[2];
	bool       m_beventRun = false;  //事件会循环处理完毕
	std::mutex m_eventListLock;
	std::deque< SLTcpClientEventImpl::_tcp_event_infoStpr>  m_eventList;  //事件列表

	std::thread   *m_pthread = nullptr;

	SLTcpServerCB* m_pcb = nullptr;
	
	std::atomic< uint32_t>   m_clientIDBase{1};
};

typedef std::shared_ptr<SLTcpServerEventImpl> SLTcpServerEventImplSPtr;

#endif